package cn.itcast.zt.java8.annotation;

import cn.hutool.core.annotation.AnnotationUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.Range;

import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.lang.reflect.Field;
import java.util.Objects;

/**
 * 参数校验基础工具类
 * create by zhangtian105 on 2021/7/14
 */
public final class ParamsCheckUtils {

    /**
     * 参数校验
     * @param obj
     * @return
     */
    public static final String checkParams(Object obj) {
        String res = null ;

        if (Objects.isNull(obj)) {
            return res ;
        }

        Field[] fields = ReflectUtil.getFields(obj.getClass()) ;
        for (Field field : fields) {
            Object fieldObj = null ;

            // NotNull针对对象类型
            if (AnnotationUtil.hasAnnotation(field, NotNull.class)) {
                fieldObj = ReflectUtil.getFieldValue(obj, field) ;

                if (Objects.isNull(fieldObj)) {
                    String notNullStr = AnnotationUtil.getAnnotationValue(field, NotNull.class, "message") ;
                    res = notNullStr ;
                    break;
                }
            }

            // NotBlank 针对字符串
            if (AnnotationUtil.hasAnnotation(field, NotBlank.class)) {
                fieldObj = ReflectUtil.getFieldValue(obj, field) ;

                if (Objects.isNull(fieldObj) || StrUtil.isBlank((String)fieldObj)) {
                    String str = AnnotationUtil.getAnnotationValue(field, NotBlank.class, "message") ;
                    res = str ;
                    break;
                }
            }

            // leng范围针对字符串
            if (AnnotationUtil.hasAnnotation(field, Length.class)) {
                fieldObj = ReflectUtil.getFieldValue(obj, field) ;

                if (Objects.nonNull(fieldObj) && StrUtil.isNotBlank((String)fieldObj)) {
                    String v = (String)fieldObj ;
                    int maxV = AnnotationUtil.getAnnotationValue(field, Length.class, "max") ;

                    if (v.length() > maxV) {
                        String str = AnnotationUtil.getAnnotationValue(field, Length.class, "message") ;
                        res = str ;
                        break;
                    }
                }
            }

            // range范围针对数字
            if (AnnotationUtil.hasAnnotation(field, Range.class)) {
                fieldObj = ReflectUtil.getFieldValue(obj, field) ;

                if (Objects.nonNull(fieldObj)) {
                    Class<?> type = field.getType() ;
                    long v = 0L ;

                    if (type == int.class || type == Integer.class) {
                        v = Long.valueOf((Integer) fieldObj) ;
                    }else if (type == long.class || type == Long.class) {
                        v = (Long) fieldObj ;
                    }else {
                        // .....
                    }

                    long minV = AnnotationUtil.getAnnotationValue(field, Range.class, "min") ;
                    long maxV = AnnotationUtil.getAnnotationValue(field, Range.class, "max") ;

                    if (v > maxV || v < minV) {
                        String str = AnnotationUtil.getAnnotationValue(field, Range.class, "message") ;
                        res = str ;
                        break;
                    }
                }
            }

            // min范围针对数字最小范围
            if (AnnotationUtil.hasAnnotation(field, Min.class)) {
                fieldObj = ReflectUtil.getFieldValue(obj, field) ;

                if (Objects.nonNull(fieldObj)) {
                    Class<?> type = field.getType() ;
                    long v = 0L ;

                    if (type == int.class || type == Integer.class) {
                        v = Long.valueOf((Integer) fieldObj) ;
                    }else if (type == long.class || type == Long.class) {
                        v = (Long) fieldObj ;
                    }else {
                        // .....
                    }

                    long minV = AnnotationUtil.getAnnotationValue(field, Min.class, "value") ;

                    if (v < minV) {
                        String str = AnnotationUtil.getAnnotationValue(field, Min.class, "message") ;
                        res = str ;
                        break;
                    }
                }
            }
        }

        return res ;
    }
}
